import 'package:extended_image/extended_image.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:interactiveviewer_gallery/hero_dialog_route.dart';
import 'package:interactiveviewer_gallery/interactiveviewer_gallery.dart';
import 'package:video_player/video_player.dart';

class DemoSourceEntity {
  int id;
  String url;
  String? previewUrl;
  String type;

  DemoSourceEntity(this.id, this.type, this.url, {this.previewUrl});
}

class InteractiveViewPage extends StatefulWidget {
  static const String sName = "/";

  const InteractiveViewPage({super.key});

  @override
  State<InteractiveViewPage> createState() {
    return _InteractiveViewPageState();
  }
}

class _InteractiveViewPageState extends State<InteractiveViewPage> {
  List<DemoSourceEntity> sourceList = [
    DemoSourceEntity(0, 'image', 'http://file.jinxianyun.com/inter_06.jpg'),
    DemoSourceEntity(1, 'image', 'http://file.jinxianyun.com/inter_05.jpg'),
    DemoSourceEntity(2, 'image', 'http://file.jinxianyun.com/inter_02.jpg'),
    DemoSourceEntity(3, 'image', 'http://file.jinxianyun.com/inter_03.gif'),
    DemoSourceEntity(4, 'video', 'http://file.jinxianyun.com/inter_04.mp4',
        previewUrl: 'http://file.jinxianyun.com/inter_04_pre.png'),
    DemoSourceEntity(5, 'video',
        'http://file.jinxianyun.com/6438BF272694486859D5DE899DD2D823.mp4',
        previewUrl: 'http://file.jinxianyun.com/102.png'),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('InteractiveViewerGallery Demo'),
      ),
      body: getImageList(),

      // Padding(
      //   padding: const EdgeInsets.only(top: 50.0),
      //   child: Wrap(
      //     children: sourceList.map((source) => _buildItem(source)).toList(),
      //   ),
      // ),
    );
  }

  Widget getImageList() {
    return GridView.builder(
        itemCount: sourceList.length,
        shrinkWrap: true,
        padding: const EdgeInsets.only(top: 50.0),
        gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 2,
          mainAxisSpacing: 12,
          mainAxisExtent: 100,
          crossAxisSpacing: 20,
        ),
        itemBuilder: (context, index) {
          return _buildItem(sourceList[index]);
        });
  }

  Widget _buildItem(DemoSourceEntity source) {
    return Hero(
      tag: source.id,
      placeholderBuilder: (BuildContext context, Size heroSize, Widget child) {
        return child;
      },
      child: GestureDetector(
        onTap: () => _openGallery(source),
        child: Stack(
          alignment: Alignment.center,
          children: [
            ExtendedImage.network(
              source.type == 'video' ? source.previewUrl! : source.url,
              width: 200,
              height: 200,
            ),
            source.type == 'video'
                ? const Icon(
                    Icons.play_arrow,
                    color: Colors.white,
                  )
                : const SizedBox(),
          ],
        ),
      ),
    );
  }

  void _openGallery(DemoSourceEntity source) {
    Navigator.of(context).push(
      HeroDialogRoute<void>(
        // DisplayGesture is just debug, please remove it when use
        // builder: (BuildContext context) => DisplayGesture(
        //   child: InteractiveviewerGallery<DemoSourceEntity>(
        //     sources: sourceList,
        //     initIndex: sourceList.indexOf(source),
        //     itemBuilder: itemBuilder,
        //     onPageChanged: (int pageIndex) {
        //       print("nell-pageIndex:$pageIndex");
        //     },
        //   ),
        // ),
        builder: (BuildContext context) =>
            InteractiveviewerGallery<DemoSourceEntity>(
          sources: sourceList,
          initIndex: sourceList.indexOf(source),
          itemBuilder: itemBuilder,
          onPageChanged: (int pageIndex) {
            print("nell-pageIndex:$pageIndex");
          },
        ),
      ),
    );
  }

  Widget itemBuilder(BuildContext context, int index, bool isFocus) {
    // DemoSourceEntity sourceEntity = sourceList[index];
    // return DemoImageItem(sourceEntity);
    DemoSourceEntity sourceEntity = sourceList[index];
    debugPrint("type:${sourceEntity.type}");
    if (sourceEntity.type == 'video') {
      return DemoVideoItem(
        sourceEntity,
        isFocus: isFocus,
      );
    } else {
      return DemoImageItem(sourceEntity);
    }
  }
}

class DemoImageItem extends StatefulWidget {
  final DemoSourceEntity source;

  const DemoImageItem(this.source, {super.key});

  @override
  State<DemoImageItem> createState() => _DemoImageItemState();
}

class _DemoImageItemState extends State<DemoImageItem> {
  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      behavior: HitTestBehavior.opaque,
      onTap: () => Navigator.of(context).pop(),
      child: Center(
        child: Hero(
          tag: widget.source.id,
          child: ExtendedImage.network(
            widget.source.url,
            width: 200,
            height: 200,
          ),
        ),
      ),
    );
  }
}

class DemoVideoItem extends StatefulWidget {
  final DemoSourceEntity source;
  final bool? isFocus;

  const DemoVideoItem(this.source, {super.key, this.isFocus});

  @override
  State<DemoVideoItem> createState() => _DemoVideoItemState();
}

class _DemoVideoItemState extends State<DemoVideoItem> {
  VideoPlayerController? _controller;
  late VoidCallback listener;
  String? localFileName;

  _DemoVideoItemState() {
    listener = () {
      if (!mounted) {
        return;
      }
      setState(() {});
    };
  }

  @override
  void initState() {
    super.initState();
    print('initState: ${widget.source.id}');
    init();
  }

  init() async {
    _controller =
        VideoPlayerController.networkUrl(Uri.parse(widget.source.url));
    // loop play
    _controller!.setLooping(true);
    await _controller!.initialize();
    setState(() {});
    _controller!.addListener(listener);
  }

  @override
  void dispose() {
    super.dispose();
    print('dispose: ${widget.source.id}');
    _controller!.removeListener(listener);
    _controller?.pause();
    _controller?.dispose();
  }

  @override
  void didUpdateWidget(covariant DemoVideoItem oldWidget) {
    super.didUpdateWidget(oldWidget);

    if (oldWidget.isFocus! && !widget.isFocus!) {
      // pause
      _controller?.pause();
    }
  }

  @override
  Widget build(BuildContext context) {
    return _controller!.value.isInitialized
        ? Stack(
            alignment: Alignment.center,
            children: [
              GestureDetector(
                onTap: () {
                  setState(() {
                    _controller!.value.isPlaying
                        ? _controller!.pause()
                        : _controller!.play();
                  });
                },
                child: Hero(
                  tag: widget.source.id,
                  child: AspectRatio(
                    aspectRatio: _controller!.value.aspectRatio,
                    child: VideoPlayer(_controller!),
                  ),
                ),
              ),
              _controller!.value.isPlaying == true
                  ? const SizedBox()
                  : const IgnorePointer(
                      ignoring: true,
                      child: Icon(
                        Icons.play_arrow,
                        size: 100,
                        color: Colors.white,
                      ),
                    ),
            ],
          )
        : Theme(
            data: ThemeData(
                cupertinoOverrideTheme:
                    const CupertinoThemeData(brightness: Brightness.dark)),
            child: const CupertinoActivityIndicator(radius: 30));
  }
}
